/*
 * Copyright (C) 2016 Nishant Srivastava
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.github.nisrulz.senseysample.slice;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.AbsButton;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentState;
import ohos.agp.components.ScaleInfo;
import ohos.agp.components.Switch;
import ohos.agp.components.Text;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.element.StateElement;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;

import com.github.nisrulz.sensey.PinchScaleDetector;
import com.github.nisrulz.sensey.Sensey;
import com.github.nisrulz.sensey.TouchTypeDetector;
import com.github.nisrulz.senseysample.ResourceTable;

/**
 * 手势
 *
 * @since 2021-04-07
 */
public class TouchAbilitySlice extends AbilitySlice implements AbsButton.CheckedStateChangedListener {
    private Component layout;
    private Text tvResult;
    private EventHandler handler;
    private Switch switchTouch;
    private Switch switchPinch;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_touch);

        handler = new EventHandler(EventRunner.getMainEventRunner());
        initViews();
        setSwitchStyle();
    }

    @Override
    public void onActive() {
        super.onActive();
        Sensey.getInstance().init();
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        stopAllDetectors();
        setAllSwitchesToFalseState();
        Sensey.getInstance().stop();
    }

    private void setAllSwitchesToFalseState() {
        switchTouch.setChecked(false);
        switchPinch.setChecked(false);
    }

    private void stopAllDetectors() {
        Sensey.getInstance().stopTouchTypeDetection();
        Sensey.getInstance().stopPinchScaleDetection();
    }

    private void initViews() {
        layout = findComponentById(ResourceTable.Id_touch_layout);
        tvResult = (Text) findComponentById(ResourceTable.Id_tv_result);
        switchTouch = (Switch) findComponentById(ResourceTable.Id_switch_touch);
        switchTouch.setCheckedStateChangedListener(this);
        switchPinch = (Switch) findComponentById(ResourceTable.Id_switch_pinch);
        switchPinch.setCheckedStateChangedListener(this);
        findComponentById(ResourceTable.Id_layout_touch)
            .setClickedListener(v -> switchTouch.setChecked(!switchTouch.isChecked()));
        findComponentById(ResourceTable.Id_layout_pinch)
            .setClickedListener(v -> switchPinch.setChecked(!switchPinch.isChecked()));
        Sensey.getInstance().startTouchTypeDetection(layout,null);
    }

    private void setResultTextView(String txt) {
        handler.postTask(() -> {
            tvResult.setText(txt);
            resetResultInView();
        });
    }

    private void resetResultInView() {
        final int delay = 1000;
        handler.postTask(() -> {
            tvResult.setText(getString(ResourceTable.String_results_show_here));
        }, delay);
    }

    @Override
    public void onCheckedChanged(AbsButton absButton, boolean isCheck) {
        switch (absButton.getId()) {
            case ResourceTable.Id_switch_touch:
                if (isCheck) {
                    startTouchTypeDetection();
                } else {
                    Sensey.getInstance().stopTouchTypeDetection();
                }
                break;
            case ResourceTable.Id_switch_pinch:
                if (isCheck) {
                    startPinchDetection();
                } else {
                    Sensey.getInstance().stopPinchScaleDetection();
                }
                break;
            default:
                break;
        }
    }

    private void startPinchDetection() {
        Sensey.getInstance()
            .startPinchScaleDetection(layout, new PinchScaleDetector.PinchScaleListener() {
                @Override
                public void onScale(ScaleInfo scaleInfo, boolean isScalingOut) {
                    if (isScalingOut) {
                        setResultTextView("Scaling Out");
                    } else {
                        setResultTextView("Scaling In");
                    }
                }

                @Override
                public void onScaleEnd(ScaleInfo scaleInfo) {
                    setResultTextView("Scaling : Stopped");
                }

                @Override
                public void onScaleStart(ScaleInfo scaleInfo) {
                    setResultTextView("Scaling : Started");
                }
            });
    }

    private void startTouchTypeDetection() {
        Sensey.getInstance()
            .startTouchTypeDetection(layout, new TouchTypeDetector.TouchTypListener() {
                @Override
                public void onDoubleTap() {
                    setResultTextView("Double Tap");
                }

                @Override
                public void onLongPress() {
                    setResultTextView("Long press");
                }

                @Override
                public void onScroll(int scrollDirection) {
                    switch (scrollDirection) {
                        case TouchTypeDetector.SCROLL_DIR_UP:
                            setResultTextView("Scrolling Up");
                            break;
                        case TouchTypeDetector.SCROLL_DIR_DOWN:
                            setResultTextView("Scrolling Down");
                            break;
                        case TouchTypeDetector.SCROLL_DIR_LEFT:
                            setResultTextView("Scrolling Left");
                            break;
                        case TouchTypeDetector.SCROLL_DIR_RIGHT:
                            setResultTextView("Scrolling Right");
                            break;
                        default:
                            break;
                    }
                }

                @Override
                public void onSingleTap() {
                    setResultTextView("Single Tap");
                }

                @Override
                public void onSwipe(int swipeDirection) {
                    switch (swipeDirection) {
                        case TouchTypeDetector.SWIPE_DIR_UP:
                            setResultTextView("Swipe Up");
                            break;
                        case TouchTypeDetector.SWIPE_DIR_DOWN:
                            setResultTextView("Swipe Down");
                            break;
                        case TouchTypeDetector.SWIPE_DIR_LEFT:
                            setResultTextView("Swipe Left");
                            break;
                        case TouchTypeDetector.SWIPE_DIR_RIGHT:
                            setResultTextView("Swipe Right");
                            break;
                        default:
                            break;
                    }
                }

                @Override
                public void onThreeFingerSingleTap() {
                    setResultTextView("Three Finger Tap");
                }

                @Override
                public void onTwoFingerSingleTap() {
                    setResultTextView("Two Finger Tap");
                }
            });
    }

    private void setSwitchStyle() {
        final int radius = 50;
        final int thumbColor = 0xFFFFFFFF;
        final int trackColor = 0xFF808080;
        ShapeElement elementThumbOn = new ShapeElement();
        elementThumbOn.setShape(ShapeElement.OVAL);
        elementThumbOn.setRgbColor(RgbColor.fromArgbInt(getColor(ResourceTable.Color_accent)));
        elementThumbOn.setCornerRadius(radius);

        ShapeElement elementThumbOff = new ShapeElement();
        elementThumbOff.setShape(ShapeElement.OVAL);
        elementThumbOff.setRgbColor(RgbColor.fromArgbInt(thumbColor));
        elementThumbOff.setCornerRadius(radius);

        ShapeElement elementTrackOn = new ShapeElement();
        elementTrackOn.setShape(ShapeElement.RECTANGLE);
        elementTrackOn.setRgbColor(RgbColor.fromArgbInt(getColor(ResourceTable.Color_divider)));
        elementTrackOn.setCornerRadius(radius);

        ShapeElement elementTrackOff = new ShapeElement();
        elementTrackOff.setShape(ShapeElement.RECTANGLE);
        elementTrackOff.setRgbColor(RgbColor.fromArgbInt(trackColor));
        elementTrackOff.setCornerRadius(radius);

        switchTouch.setTrackElement(trackElementInit(elementTrackOn, elementTrackOff));
        switchTouch.setThumbElement(thumbElementInit(elementThumbOn, elementThumbOff));

        switchPinch.setTrackElement(trackElementInit(elementTrackOn, elementTrackOff));
        switchPinch.setThumbElement(thumbElementInit(elementThumbOn, elementThumbOff));
    }

    private StateElement trackElementInit(ShapeElement on, ShapeElement off) {
        StateElement trackElement = new StateElement();
        trackElement.addState(new int[]{ComponentState.COMPONENT_STATE_CHECKED}, on);
        trackElement.addState(new int[]{ComponentState.COMPONENT_STATE_EMPTY}, off);
        return trackElement;
    }

    private StateElement thumbElementInit(ShapeElement on, ShapeElement off) {
        StateElement thumbElement = new StateElement();
        thumbElement.addState(new int[]{ComponentState.COMPONENT_STATE_CHECKED}, on);
        thumbElement.addState(new int[]{ComponentState.COMPONENT_STATE_EMPTY}, off);
        return thumbElement;
    }
}
